﻿using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;

namespace Client.Hotfix
{
    /// <summary>
    /// 无限循环列表（回调版本）
    /// </summary>
    public class InfiniteScrollView : MonoBehaviour
    {
        [SerializeField] private ScrollRect scrollRect;
        [SerializeField] private RectTransform content;
        [SerializeField] private GameObject itemPrefab;
        [SerializeField] private int poolSize = 10;
        [SerializeField] private float itemHeight = 100f;
        private int dataCount = 0;
        [SerializeField] private float spacing = 10f;

        private List<GameObject> itemPool = new List<GameObject>();
        private int currentStartIndex = 0;
        private bool isDataInitialized = false;

        // 数据更新回调
        public Action<GameObject, int> OnItemUpdate { get; set; }

        void Start()
        {
            SetupContentLayout();
            InitializePool();
            scrollRect.onValueChanged.AddListener(OnScrollValueChanged);

            HideAllItems();
        }

        private void SetupContentLayout()
        {
            if (content == null) return;

            content.anchorMin = new Vector2(0, 1);
            content.anchorMax = new Vector2(1, 1);
            content.pivot = new Vector2(0.5f, 1);
            content.anchoredPosition = Vector2.zero;
            content.sizeDelta = new Vector2(content.sizeDelta.x, 0);
        }

        private void InitializePool()
        {
            foreach (var item in itemPool)
            {
                if (item != null) Destroy(item);
            }
            itemPool.Clear();

            for (int i = 0; i < poolSize; i++)
            {
                GameObject item = Instantiate(itemPrefab, content);
                item.SetActive(false);

                RectTransform itemRect = item.GetComponent<RectTransform>();
                if (itemRect != null)
                {
                    itemRect.anchorMin = new Vector2(0, 1);
                    itemRect.anchorMax = new Vector2(1, 1);
                    itemRect.pivot = new Vector2(0.5f, 1);
                    itemRect.sizeDelta = new Vector2(0, itemHeight);
                }

                itemPool.Add(item);
            }

            UpdateContentSize();
        }

        private void HideAllItems()
        {
            foreach (var item in itemPool)
            {
                if (item != null)
                    item.SetActive(false);
            }
            currentStartIndex = 0;
        }

        private void ResetScrollToTop()
        {
            if (scrollRect != null)
            {
                scrollRect.verticalNormalizedPosition = 1f;
            }
            currentStartIndex = 0;
        }

        private void OnScrollValueChanged(Vector2 pos)
        {
            if (!isDataInitialized || dataCount == 0) return;
            UpdateVisibleItems();
        }

        private void UpdateVisibleItems()
        {
            if (dataCount <= poolSize)
            {
                currentStartIndex = 0;
                UpdateItemsPosition();
                return;
            }

            float scrollPosition = Mathf.Clamp01(1 - scrollRect.verticalNormalizedPosition);
            float totalItemHeight = itemHeight + spacing;
            float visibleHeight = poolSize * totalItemHeight;
            float totalHeight = dataCount * totalItemHeight - spacing;

            int newStartIndex = Mathf.FloorToInt((totalHeight - visibleHeight) * scrollPosition / totalItemHeight);
            newStartIndex = Mathf.Clamp(newStartIndex, 0, Mathf.Max(0, dataCount - poolSize));

            if (scrollPosition > 0.95f && dataCount > poolSize)
            {
                newStartIndex = dataCount - poolSize;
            }

            if (newStartIndex != currentStartIndex)
            {
                currentStartIndex = newStartIndex;
                UpdateItemsPosition();
            }
        }

        private void UpdateItemsPosition()
        {
            float totalItemHeight = itemHeight + spacing;

            for (int i = 0; i < poolSize; i++)
            {
                int dataIndex = currentStartIndex + i;

                if (dataIndex < dataCount)
                {
                    itemPool[i].SetActive(true);
                    RectTransform itemRect = itemPool[i].GetComponent<RectTransform>();
                    float yPosition = -dataIndex * totalItemHeight;
                    itemRect.anchoredPosition = new Vector2(0, yPosition);

                    // 通过回调更新数据
                    UpdateItemData(itemPool[i], dataIndex);
                }
                else
                {
                    itemPool[i].SetActive(false);
                }
            }
        }

        private void UpdateContentSize()
        {
            float totalHeight = dataCount * (itemHeight + spacing) - spacing;

            RectTransform viewport = scrollRect.viewport != null ? scrollRect.viewport : scrollRect.GetComponent<RectTransform>();
            float viewportHeight = viewport.rect.height;

            if (totalHeight < viewportHeight)
            {
                totalHeight = viewportHeight;
            }

            content.sizeDelta = new Vector2(content.sizeDelta.x, totalHeight);
        }

        private void UpdateItemData(GameObject item, int dataIndex)
        {
            // 通过回调让外部更新数据
            OnItemUpdate?.Invoke(item, dataIndex);
            item.name = $"Item_{dataIndex}";
        }

        /// <summary>
        /// 设置数据长度（外部调用）
        /// </summary>
        /// <param name="count">数据总数</param>
        public void SetDataCount(int count)
        {
            dataCount = Mathf.Max(0, count);
            isDataInitialized = dataCount > 0;

            UpdateContentSize();
            ResetScrollToTop();
            UpdateItemsPosition();
        }

        /// <summary>
        /// 刷新显示（数据变化后调用）
        /// </summary>
        public void Refresh()
        {
            if (!isDataInitialized) return;
            UpdateItemsPosition();
        }

        /// <summary>
        /// 刷新指定项的数据
        /// </summary>
        public void RefreshItem(int dataIndex)
        {
            if (!isDataInitialized || dataIndex < 0 || dataIndex >= dataCount) return;

            // 查找该数据项当前是否可见
            for (int i = 0; i < poolSize; i++)
            {
                int currentDataIndex = currentStartIndex + i;
                if (currentDataIndex == dataIndex && currentDataIndex < dataCount)
                {
                    UpdateItemData(itemPool[i], dataIndex);
                    break;
                }
            }
        }

        /// <summary>
        /// 清空所有数据
        /// </summary>
        public void ClearData()
        {
            dataCount = 0;
            isDataInitialized = false;

            UpdateContentSize();
            HideAllItems();
        }

        /// <summary>
        /// 获取当前数据数量
        /// </summary>
        public int GetDataCount()
        {
            return dataCount;
        }

        /// <summary>
        /// 获取当前显示的起始索引
        /// </summary>
        public int GetCurrentStartIndex()
        {
            return currentStartIndex;
        }

        /// <summary>
        /// 获取当前显示的结束索引
        /// </summary>
        public int GetCurrentEndIndex()
        {
            return Mathf.Min(currentStartIndex + poolSize - 1, dataCount - 1);
        }

        public void ScrollToBottom()
        {
            if (dataCount <= poolSize)
            {
                currentStartIndex = 0;
            }
            else
            {
                currentStartIndex = dataCount - poolSize;
            }

            scrollRect.verticalNormalizedPosition = 0f;
            UpdateItemsPosition();
        }

        public void ScrollToTop()
        {
            currentStartIndex = 0;
            scrollRect.verticalNormalizedPosition = 1f;
            UpdateItemsPosition();
        }

        public void SetSpacing(float newSpacing)
        {
            spacing = Mathf.Max(0, newSpacing);
            if (isDataInitialized)
            {
                UpdateContentSize();
                UpdateItemsPosition();
            }
        }

        public void SetItemHeight(float newHeight)
        {
            itemHeight = Mathf.Max(1, newHeight);
            if (isDataInitialized)
            {
                UpdateContentSize();
                UpdateItemsPosition();
            }
        }

 
    }
}